epiworld

A fast multi-language library for epi ABMs

George G. Vega Yon

The University of Utah

Derek Meyer
Milo Banks
Matthew Samore

2024-09-03

Hello world!

#include "epiworld.hpp"

int main() {
1    epiworld::epimodels::ModelSIR<> model(
        "Flu", // Name
        .01,   // Initial infected
        .2,    // Transmission rate
        .14    // Recovery rate
        );

2    model.agents_smallworld(
        100000, // Population size
        10,     // Number of contacts
        false,  // Directed = false
        0.01    // Rewiring probability
        );

    // Running and printing!
3    model.run(100, 771);
4    model.print();

    return 0;
}
1
Create a SIR model.
2
Create a small-world network.
3
Run the model for 100 days.
4
Print the results.
> ./hello-world.o
_________________________________________________________________________
Running the model...
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| done.
 done.
________________________________________________________________________________
________________________________________________________________________________
SIMULATION STUDY

Name of the model   : Susceptible-Infected-Recovered (SIR)
Population size     : 100000
Agents' data        : (none)
Number of entities  : 0
Days (duration)     : 100 (of 100)
Number of viruses   : 1
Last run elapsed t  : 116.00ms
Last run speed      : 85.53 million agents x day / second
Rewiring            : off

Global events:
 (none)

Virus(es):
 - covid

Tool(s):
 (none)

Model parameters:
 - Recovery rate     : 0.1400
 - Transmission rate : 0.2000

Distribution of the population at time 100:
  - (0) Susceptible :  99000 -> 495
  - (1) Infected    :   1000 -> 213
  - (2) Recovered   :      0 -> 99292

Transition Probabilities:
 - Susceptible  0.95  0.05  0.00
 - Infected     0.00  0.86  0.14
 - Recovered    0.00  0.00  1.00

About the software

Light

  • Built on the C++ standard library.
  • Easy to port to other languages (R, Python).

A Framework

  • Highly modular.
  • User-defined states and update dynamics.

Fast

  • Out-of-the-box parallelism.
  • Up to 100 million agents-day per second.

Complex

  • Multi-virus.
  • Evolving virus.
  • Heterogeneous populations.

Open-source and CDC-funded.

Compared to other libraries

Simulated a network SIR with 50 K agents:

  • Covasim (Python): ~ 1 second (although the model is more complex, SIRd).
  • Epiworld is 3x faster than igraph, 14x faster than AnyLogic, and 28x faster than ABM.

Example

A complex model

  • SEIR model.

  • Population of 200 K agents in a connected graph.

  • Two initial viruses: COVID-19 and the Flu.

  • Flu has 0.001 probability of mutating. These change the transmission rate.

  • Policy: 30% of vaccinated agents.

  • NPI: full isolation trigerred when the daily cases are above 1,000. Cools downs when below 100.

Running the model...
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| done.
 done.
________________________________________________________________________________
________________________________________________________________________________
SIMULATION STUDY

Name of the model   : Susceptible-Exposed-Infected-Removed (SEIR) (connected)
Population size     : 200000
Agents' data        : (none)
Number of entities  : 0
Days (duration)     : 180 (of 180)
Number of viruses   : 205
Last run elapsed t  : 1.00s
Last run speed      : 33.36 million agents x day / second
Rewiring            : off

Global events:
 - Update infected individuals (runs daily)
 - Full isolate (runs daily)

Virus(es):
 - Covid-19
 - Flu
 ...and 203 more variants...

Tool(s):
 - Vaccine

Model parameters:
 - Avg. Incubation days : 7.0000
 - Contact rate         : 0.3000
 - Prob. Recovery       : 0.1429
 - Prob. Transmission   : 0.3000

Distribution of the population at time 180:
  - (0) Susceptible : 199960 -> 128884
  - (1) Exposed     :     40 -> 1754
  - (2) Infected    :      0 -> 2261
  - (3) Recovered   :      0 -> 67101

Transition Probabilities:
 - Susceptible  1.00  0.00  0.00  0.00
 - Exposed      0.00  0.84  0.16  0.00
 - Infected     0.00  0.00  0.80  0.20
 - Recovered    0.00  0.00  0.00  1.00

Full code available here.

Short example: Complex model (cont.)

  • Virus can be multiple.
  • Rates/probabilities can be either fixed or functional (e.g., transmission rate depending on age).
  • Mutation is evaluated at each time step.
// Creating the model
1Virus<> flu("Flu");
2flu.set_incubation(5.0);
flu.set_prob_infecting(0.2);
flu.set_prob_recovery(1.0/7.0);

// Adding mutation
3flu.set_mutation(flumutates);

// How will it be distributed 
4flu.set_distribution(
  distribute_virus_randomly<>(20, false)
  ); 

// Adding the virus to the model
5flu.set_state(1, 3);
model.add_virus(flu);
1
Create a new virus.
2
Define the virus parameters.
3
Define a mutation function.
4
Define how the virus will be distributed.
5
Add the virus to the model.

Some decisions:

  1. Why C++?

  2. Why discrete time?

Challenges

  • How to maximize usage?

  • How to make it user-friendly?

  • Ease of use vs. flexibility vs. speed.

Thanks!

George G. Vega Yon, Ph.D.